import * as Sequelize from 'sequelize';

import { db } from '../../db';

/* -------------------------------------------------------------------------- */
/*                                    TYPE                                    */
/* -------------------------------------------------------------------------- */

interface Attributes {
  /* ------------------------------- attributes ------------------------------- */

  readonly id: number;
  readonly name: string;

  readonly rate: number;

  readonly residentRequests: number;
  readonly nonResidentRequests: number;

  /* ------------------------------ / attributes ------------------------------ */
}

type CreationAttributes = Sequelize.Optional<Attributes, 'id'>;

export interface Type extends Sequelize.Model<Attributes, CreationAttributes>, Attributes {}

/* -------------------------------------------------------------------------- */
/*                                   / TYPE                                   */
/* -------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------- */
/*                                    MODEL                                   */
/* -------------------------------------------------------------------------- */

const name = { singular: 'country', plural: 'countries' };

export const Model = db.define<Type>(
  name.plural,
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  {
    id: { type: Sequelize.DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },

    name: { type: Sequelize.DataTypes.STRING(255), allowNull: false },

    rate: { type: Sequelize.DataTypes.INTEGER, allowNull: false },

    residentRequests: { type: Sequelize.DataTypes.INTEGER, allowNull: false },

    nonResidentRequests: { type: Sequelize.DataTypes.INTEGER, allowNull: false },
  },
  {
    name,
    freezeTableName: true,
    timestamps: false,
  }
);

/* -------------------------------------------------------------------------- */
/*                                   / MODEL                                  */
/* -------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------- */
/*                                    SYNC                                    */
/* -------------------------------------------------------------------------- */

/* -------------------------------- function -------------------------------- */

export const sync = async () => {
  const transaction = await db.transaction();

  try {
    console.time('[sync models.Country]');

    for await (const syncDataItem of syncData) {
      const record = await Model.findOne({ where: { id: syncDataItem.id }, transaction });

      if (!!record) {
        console.time(`[sync models.Country] UPDATED ${syncDataItem.id}`);

        record.set({
          name: syncDataItem.name,
          rate: syncDataItem.rate,
          residentRequests: syncDataItem.residentRequests,
          nonResidentRequests: syncDataItem.nonResidentRequests,
        });

        await record.save({ transaction });

        console.timeEnd(`[sync models.Country] UPDATED ${syncDataItem.id}`);
      } else {
        console.time(`[sync models.Country] CREATED ${syncDataItem.id}`);

        await Model.create(syncDataItem, { transaction });

        console.timeEnd(`[sync models.Country] CREATED ${syncDataItem.id}`);
      }
    }

    await transaction.commit();
  } catch (error) {
    await transaction.rollback();
    console.error('[sync models.Country]', error);
  } finally {
    console.timeEnd('[sync models.Country]');
  }
};

/* ------------------------------- / function ------------------------------- */

/* ---------------------------------- data ---------------------------------- */

const syncData: ReadonlyArray<CreationAttributes> = [
  {
    id: 1,
    name: 'Китай',
    rate: 1,
    residentRequests: 415829,
    nonResidentRequests: 110583,
  },
  {
    id: 2,
    name: 'США',
    rate: 2,
    residentRequests: 247750,
    nonResidentRequests: 255832,
  },
  {
    id: 3,
    name: 'Южная Корея',
    rate: 4,
    residentRequests: 138034,
    nonResidentRequests: 40890,
  },
  {
    id: 4,
    name: 'Россия',
    rate: 7,
    residentRequests: 26495,
    nonResidentRequests: 14919,
  },
  {
    id: 5,
    name: 'Великобритания',
    rate: 11,
    residentRequests: 15343,
    nonResidentRequests: 6916,
  },
  {
    id: 6,
    name: 'Украина',
    rate: 23,
    residentRequests: 2649,
    nonResidentRequests: 2604,
  },
  {
    id: 7,
    name: 'Эквадор',
    rate: 54,
    residentRequests: 4,
    nonResidentRequests: 690,
  },
];

/* --------------------------------- / data --------------------------------- */

/* -------------------------------------------------------------------------- */
/*                                   / SYNC                                   */
/* -------------------------------------------------------------------------- */
